package top.v5it.japi.plus.common.tuple;

/**
 * 元组工具类
 *
 * @author zhanpu
 * @date 2022/8/23
 */
public abstract class Tuples {

    @SuppressWarnings("rawtypes")
    public static Tuple1 fromArray(Object[] list) {
        if (list != null && list.length >= 1) {
            switch (list.length) {
                case 1:
                    return of(list[0]);
                case 2:
                    return of(list[0], list[1]);
                case 3:
                    return of(list[0], list[1], list[2]);
                case 4:
                    return of(list[0], list[1], list[2], list[3]);
                case 5:
                    return of(list[0], list[1], list[2], list[3], list[4]);
                case 6:
                    return of(list[0], list[1], list[2], list[3], list[4], list[5]);
                case 7:
                    return of(list[0], list[1], list[2], list[3], list[4], list[5], list[6]);
                case 8:
                    return of(list[0], list[1], list[2], list[3], list[4], list[5], list[6], list[7]);
                default:
                    throw new IllegalArgumentException("too many arguments (" + list.length + "), need between 2 and 8 values");
            }
        } else {
            throw new IllegalArgumentException("null or too small array, need between 2 and 8 values");
        }
    }

    public static <T1> Tuple1<T1> of(T1 one) {
        return new Tuple1<>(one);
    }

    public static <T1, T2> Tuple2<T1, T2> of(T1 one, T2 two) {
        return new Tuple2<>(one, two);
    }

    public static <T1, T2, T3> Tuple3<T1, T2, T3> of(T1 one, T2 two, T3 three) {
        return new Tuple3<>(one, two, three);
    }

    public static <T1, T2, T3, T4> Tuple4<T1, T2, T3, T4> of(T1 one, T2 two, T3 three, T4 four) {
        return new Tuple4<>(one, two, three, four);
    }

    public static <T1, T2, T3, T4, T5> Tuple5<T1, T2, T3, T4, T5> of(T1 one, T2 two, T3 three, T4 four, T5 five) {
        return new Tuple5<>(one, two, three, four, five);
    }

    public static <T1, T2, T3, T4, T5, T6> Tuple6<T1, T2, T3, T4, T5, T6> of(T1 one, T2 two, T3 three, T4 four, T5 five, T6 six) {
        return new Tuple6<>(one, two, three, four, five, six);
    }

    public static <T1, T2, T3, T4, T5, T6, T7> Tuple7<T1, T2, T3, T4, T5, T6, T7> of(T1 one, T2 two, T3 three, T4 four, T5 five, T6 six, T7 seven) {
        return new Tuple7<>(one, two, three, four, five, six, seven);
    }

    public static <T1, T2, T3, T4, T5, T6, T7, T8> Tuple8<T1, T2, T3, T4, T5, T6, T7, T8> of(T1 one, T2 two, T3 three, T4 four, T5 five, T6 six, T7 seven, T8 eight) {
        return new Tuple8<>(one, two, three, four, five, six, seven, eight);
    }

    public static <T1, T2, T3, T4, T5, T6, T7, T8, T9> Tuple9<T1, T2, T3, T4, T5, T6, T7, T8, T9> of(T1 one, T2 two, T3 three, T4 four, T5 five, T6 six, T7 seven, T8 eight, T9 nine) {
        return new Tuple9<>(one, two, three, four, five, six, seven, eight, nine);
    }

    static StringBuilder tupleStringRepresentation(Object... values) {
        StringBuilder sb = new StringBuilder();

        for (int i = 0; i < values.length; ++i) {
            Object t = values[i];
            if (i != 0) {
                sb.append(',');
            }

            if (t != null) {
                sb.append(t);
            }
        }

        return sb;
    }
}
